package com.sfx.concurrent.demo.concurrent.TestWaitNotify;

import lombok.extern.slf4j.Slf4j;

/**
 * Description:
 * 还有一个缺陷就是,小南在等待的时候条件用的if,意味着小南只等一次,之后就不等了
 * 改进就是 : 在进入wait条件,循环改成while,这样小南等不到烟就一直等着
 */

@Slf4j(topic = "c.TestWaitNotify4")
public class TestWaitNotify4 {
    private static final Object room = new Object();
    private static boolean isCigarette = false;
    private static boolean isTakeOut = false;
    public static void main(String[] args) throws InterruptedException {
        //小南等烟
        new Thread(()->{
            synchronized (room) {
                log.debug("是否有香烟 : " +isCigarette);
                while(!isCigarette){
                    log.debug("没有香烟,干不了活,等一会");
                    try {
                        room.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.debug("是否有香烟 : " +isCigarette);
                if(isCigarette){
                    log.debug("小南开始干活");
                }else {
                    log.debug("小南没有干活");
                }
            }
        },"小南").start();

        //小女等外卖
        new Thread(()->{
            synchronized (room) {
                log.debug("是否有外卖 : " +isTakeOut);
                if(!isTakeOut){
                    log.debug("没有外卖,干不了活,等一会");
                    try {
                        room.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.debug("是否有外卖 : " +isTakeOut);
                if(isTakeOut){
                    log.debug("小女干活");
                }else {
                    log.debug("小女没有干活");
                }
            }

        },"小女").start();

        Thread.sleep(1000);
        new Thread(()->{
            synchronized (room){
                isTakeOut = true;
                log.debug("外卖到了");
                room.notifyAll();//解决部分线程虚假唤醒问题
            }
        }).start();

        Thread.sleep(1000);
        new Thread(()->{
            synchronized (room){
                isCigarette = true;
                log.debug("烟到了");
                room.notifyAll();
            }
        },"送烟的").start();
    }
}